//==================================================================
//  Copyright (C) 2006-2007  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
/// @file	psys_types.h
///
///
///
//==================================================================

#ifndef PSYS_TYPES_H
#define PSYS_TYPES_H

//==================================================================
//== Standard Types
//==================================================================
#if defined(_MSC_VER)
	#define ALIGN64		__declspec(align(64))
	#define ALIGN16		
	#define PALIGN(_X_)	__declspec(align(_X_))
#else
	#error	"Platform dependent stuff is missing."
#endif

#ifndef NULL
	#define	NULL	0
#endif

#if defined(WIN32)
	typedef struct { unsigned int	x, y, z, w; }	u_long128;
	typedef unsigned __int64						u_long64;
	typedef __int64									long64;
#else
	#error	"Platform dependent stuff is missing."
#endif

#if !defined(_WINSOCKAPI_) && !defined(_SYS_TYPES_H)
	typedef unsigned char		u_char;
	typedef unsigned short		u_short;
	typedef unsigned int		u_int;
	typedef unsigned long		u_long;
	#define _SYS_TYPES_H
#endif
	typedef signed char			s_char;

/*
typedef unsigned char		u_char4[4];

typedef short				  short2[2];
typedef unsigned short		u_short2[2];
typedef short				  short3[3];
typedef unsigned short		u_short3[3];

typedef	int					  int3[3];
typedef unsigned int		u_int3[3];
typedef	int					  int3[3];
typedef unsigned int		u_int3[3];

typedef float				float2[2];
typedef float				float3[3];
typedef float				float4[4];
*/

typedef enum
{
	POK = 0,
	PERROR = -1,
} PError;

//==================================================================
namespace PSYS {

//==================================================================
class RectF
{
public:
	float	_x, _y, _w, _h;

	RectF( float x, float y, float w, float h ): _x(x), _y(y), _w(w), _h(h)
	{
	}

	RectF(): _x(0), _y(0), _w(0), _h(0)
	{
	}

	void PositionInside( const RectF &outer_rect, int align_x=0, int align_y=0 )
	{
		if ( align_x < 0 )	_x = outer_rect._x;							else
		if ( align_x > 0 )	_x = outer_rect._x + outer_rect._w - _w;	else
							_x = outer_rect._x + (outer_rect._w - _w) * 0.5f;

		if ( align_y < 0 )	_y = outer_rect._y;							else
		if ( align_y > 0 )	_y = outer_rect._y + outer_rect._h - _h;	else
							_y = outer_rect._y + (outer_rect._h - _h) * 0.5f;
	}

	void Inset( float off_x, float off_y )
	{
		_x += off_x;
		_y += off_y;
		_w -= off_x*2;
		_h -= off_y*2;
	}
};

};

//==================================================================
//== Endianness
//==================================================================
static __inline u_short PSYS_ENDIAN_SWAP_16( u_short a )
{
	return (u_short)(((u_short)(a >> 8)) | (u_short)(a << 8));
}
static __inline u_int PSYS_ENDIAN_SWAP_32( u_int a )
{
	return (a >> 24) |						// 3 -> 0
		   ((a & 0xff) << 24) |				// 0 -> 3
		   ((a & 0xff00) << 8) |			// 1 -> 2
		   ((a >> 8) & 0xff00);				// 2 -> 1
}

#if defined(WIN32)
	#define PSYS_LITTLEENDIAN

	#define PSYS_ENDIAN_MAKE_L16(_A_)	(_A_)
	#define PSYS_ENDIAN_MAKE_L32(_A_)	(_A_)
	#define PSYS_ENDIAN_MAKE_B16(_A_)	PSYS_ENDIAN_SWAP_16(_A_)
	#define PSYS_ENDIAN_MAKE_B32(_A_)	PSYS_ENDIAN_SWAP_32(_A_)

	#define PSYS_ENDIAN_FIX_L16(_A_)	(_A_)
	#define PSYS_ENDIAN_FIX_L32(_A_)	(_A_)
	#define PSYS_ENDIAN_FIX_B16(_A_)	((_A_) = PSYS_ENDIAN_SWAP_16(_A_))
	#define PSYS_ENDIAN_FIX_B32(_A_)	((_A_) = PSYS_ENDIAN_SWAP_32(_A_))

#else
	#error	"Platform dependent stuff is missing."
/*
	#define PSYS_BIGENDIAN

	#define PSYS_ENDIAN_MAKE_L16(_A_)	PSYS_ENDIAN_SWAP_16(_A_)
	#define PSYS_ENDIAN_MAKE_L32(_A_)	PSYS_ENDIAN_SWAP_32(_A_)
	#define PSYS_ENDIAN_MAKE_B16(_A_)	(_A_)
	#define PSYS_ENDIAN_MAKE_B32(_A_)	(_A_)

	#define PSYS_ENDIAN_FIX_L16( _A_ )	((_A_) = PSYS_ENDIAN_SWAP_16(_A_))
	#define PSYS_ENDIAN_FIX_L32( _A_ )	((_A_) = PSYS_ENDIAN_SWAP_32(_A_))
	#define PSYS_ENDIAN_FIX_B16( _A_ )	(_A_)
	#define PSYS_ENDIAN_FIX_B32( _A_ )	(_A_)
*/
#endif

#define PSYS_ENDIAN_FIX_L_DWORD			PSYS_ENDIAN_FIX_L32
#define PSYS_ENDIAN_FIX_L_LONG			PSYS_ENDIAN_FIX_L32
#define PSYS_ENDIAN_FIX_L_WORD			PSYS_ENDIAN_FIX_L16
#define PSYS_ENDIAN_FIX_L_INT			PSYS_ENDIAN_FIX_L32
#define PSYS_ENDIAN_FIX_L_UINT			PSYS_ENDIAN_FIX_L32
#define PSYS_ENDIAN_FIX_L_SHORT			PSYS_ENDIAN_FIX_L16
#define PSYS_ENDIAN_FIX_L_USHORT		PSYS_ENDIAN_FIX_L16
#define PSYS_ENDIAN_FIX_L_FLOAT(_A_)	PSYS_ENDIAN_FIX_L32( *(u_int *)&(_A_) )

#define PSYS_ENDIAN_FIX_B_DWORD			PSYS_ENDIAN_FIX_B32
#define PSYS_ENDIAN_FIX_B_LONG			PSYS_ENDIAN_FIX_B32
#define PSYS_ENDIAN_FIX_B_WORD			PSYS_ENDIAN_FIX_B16
#define PSYS_ENDIAN_FIX_B_INT			PSYS_ENDIAN_FIX_B32
#define PSYS_ENDIAN_FIX_B_UINT			PSYS_ENDIAN_FIX_B32
#define PSYS_ENDIAN_FIX_B_SHORT			PSYS_ENDIAN_FIX_B16
#define PSYS_ENDIAN_FIX_B_USHORT		PSYS_ENDIAN_FIX_B16
#define PSYS_ENDIAN_FIX_B_FLOAT(_A_)	PSYS_ENDIAN_FIX_B32( *(u_int *)&(_A_) )

#define PSYS_ENDIAN_FIX_L_PTR(_A_)		PSYS_ENDIAN_FIX_L32( *(u_int *)&(_A_) )
#define PSYS_ENDIAN_FIX_B_PTR(_A_)		PSYS_ENDIAN_FIX_B32( *(u_int *)&(_A_) )

#define PSYS_ENDIAN_MAKE_L_DWORD		PSYS_ENDIAN_MAKE_L32
#define PSYS_ENDIAN_MAKE_L_LONG			PSYS_ENDIAN_MAKE_L32
#define PSYS_ENDIAN_MAKE_L_WORD			PSYS_ENDIAN_MAKE_L16
#define PSYS_ENDIAN_MAKE_B_DWORD		PSYS_ENDIAN_MAKE_B32
#define PSYS_ENDIAN_MAKE_B_LONG			PSYS_ENDIAN_MAKE_B32
#define PSYS_ENDIAN_MAKE_B_WORD			PSYS_ENDIAN_MAKE_B16


#endif
